package com.test.A32;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletRegistrationBean;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.ErrorPageRegistrar;
import org.springframework.boot.web.server.ErrorPageRegistrarBeanPostProcessor;
import org.springframework.boot.web.server.ErrorPageRegistry;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.servlet.view.BeanNameViewResolver;

@Configuration
public class WebConfig {
	/***
	 * 创建tomcat容器
	 * 
	 * @return
	 */
	@Bean
	public TomcatServletWebServerFactory servletWebServerFactory() {
		return new TomcatServletWebServerFactory();
	}

	/***
	 * 创建DispatcherServlet对象
	 * 
	 * @return
	 */
	@Bean
	public DispatcherServlet dispatcherServlet() {
		return new DispatcherServlet();
	}

	/****
	 * 把DispatcherServlet放到tomcat中 前三个是必须有的 如果是web的方式
	 * 
	 * @param dispatcherServlet
	 * @return
	 */
	@Bean
	public DispatcherServletRegistrationBean servletRegistrationBean(DispatcherServlet dispatcherServlet) {
		DispatcherServletRegistrationBean registrationBean = new DispatcherServletRegistrationBean(dispatcherServlet,
				"/");
		registrationBean.setLoadOnStartup(1);
		return registrationBean;
	}

	/****
	 * @RequestMapping
	 * @return
	 */
	@Bean // @RequestMapping
	public RequestMappingHandlerMapping requestMappingHandlerMapping() {
		return new RequestMappingHandlerMapping();
	}

	/***
	 * RequestMappingHandlerAdapter
	 * 
	 * @return
	 */
	@Bean // 注意默认的 RequestMappingHandlerAdapter 不会带 jackson 转换器
	public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
		RequestMappingHandlerAdapter handlerAdapter = new RequestMappingHandlerAdapter();
		handlerAdapter.setMessageConverters(Arrays.asList(new MappingJackson2HttpMessageConverter()));
		return handlerAdapter;
	}

	@Bean // 修改了 Tomcat 服务器默认错误地址
	public ErrorPageRegistrar errorPageRegistrar() { // 出现错误，会使用请求转发 forward 跳转到 error 地址
		return webServerFactory -> webServerFactory.addErrorPages(new ErrorPage("/error"));
	}

	/**
	 * 内部类的写法 public ErrorPageRegistrar errorPageRegistrar1() { return new
	 * ErrorPageRegistrar() {
	 * 
	 * @Override public void registerErrorPages(ErrorPageRegistry registry) {
	 * 
	 * 
	 *           } }; }
	 **/

	/***
	 * TomcatServletWebServerFactory创建后，在执行这个ErrorPageRegistrarBeanPostProcessor的创建，然后执行
	 * ErrorPageRegistrar的内容
	 * 
	 * @return
	 */
	@Bean
	public ErrorPageRegistrarBeanPostProcessor errorPageRegistrarBeanPostProcessor() {
		return new ErrorPageRegistrarBeanPostProcessor();
	}

	@Controller
	public static class MyController {
		@RequestMapping("test")
		public ModelAndView test() {
			int i = 1 / 0;
			return null;
		}

		/***
		 * 异常处理的请求  spring的
		 * 
		 * @param request
		 * @return
		 */
		/*
		 * @RequestMapping("/error")
		 * 
		 * @ResponseBody public Map<String, Object> error(HttpServletRequest request) {
		 * Throwable e = (Throwable)
		 * request.getAttribute(RequestDispatcher.ERROR_EXCEPTION); Map map = new
		 * HashMap(); map.put("error", e.getMessage()); return map; }
		 */
 
		    /****
		     * 使用springboot的BasicErrorController来处理
		     * @return
		     */
		/*** 
		    @Bean
		    public BasicErrorController basicErrorController() {
		        return new BasicErrorController(new DefaultErrorAttributes(), new ErrorProperties());
		    }
		    ***/
		
		    @Bean
		    public BasicErrorController basicErrorController() {
		    	ErrorProperties errorProperties = new ErrorProperties();
		        errorProperties.setIncludeException(true);//得到异常的内容
		        return new BasicErrorController(new DefaultErrorAttributes(), errorProperties);
		    }
	}
	
	/***
	 * 如果使用的是get的方式访问  需要重新定义一个视图 
	 * @return
	 */
    @Bean
    public View error() {
        return new View() {
            @Override
            public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
                System.out.println(model);
                response.setContentType("text/html;charset=utf-8");
                response.getWriter().print("<h3>服务器内部错误</h3>");
            }
        };
    }

    @Bean
    public ViewResolver viewResolver() {
        return new BeanNameViewResolver();
    }

}